import Result from '@/structure/result';
import OtpUtils from '@/utils/otp';
import UserUtils from '@/utils/user';
import Axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios';
import {Message} from 'element-ui';

const BASE_URL = process.env.VUE_APP_API_URL;

/**
 * ID
 */
export type ID = string | number | null | undefined;

/**
 * 参数表
 */
export interface PARAMS {
  [key: string]: any;
}

/**
 * http请求
 */
class Http {
  /**
   * axios实例
   */
  public axiosInstance: AxiosInstance;

  /**
   * 默认配置
   */
  public defaults: AxiosRequestConfig;

  constructor() {
    this.defaults = {
      baseURL: BASE_URL,
      headers: {},
      withCredentials: true
    };

    this.axiosInstance = Axios.create(this.defaults);
    this.axiosInstance.interceptors.request.use((config) => {
      const token = UserUtils.getAccessToken();
      if (token) {
        config.headers.Authorization = token;
      }
      const otp = OtpUtils.getOtp();
      if (otp) {
        config.headers.OTP = otp;
      }
      return config;
    }, (err) => {
      return Promise.reject({
        errorCode: 400,
        message: '请求发生错误,请稍后再试!' + err
      });
    });
    this.axiosInstance.interceptors.response.use((result) => {
      if (result.request.responseType === 'blob' || result.request.responseType === 'arraybuffer'
        || result.request.responseType === 'document' || result.request.responseType === 'text') {
        return result.data;
      }

      const res = result.data;
      const status = res.status;
      const errorCode = res.errorCode;
      if (status) {
        return typeof res.data !== 'undefined' ? res.data : status;
      }

      if (errorCode === 401) {
        location.href = '/ControlPanel/login';
      } else if (errorCode < 900 || errorCode > 999) {
        Message.error(res.message);
      }

      return Promise.reject({
        errorCode,
        message: res.message
      });
    }, (err) => {
      return Promise.reject({
        errorCode: 400,
        message: '网络请求错误,请稍后再试!' + err
      });
    });
  }

  /**
   * get请求
   * @param url 请求地址
   * @param config 请求参数
   * @return 响应
   */
  protected get0<T = any, R = AxiosResponse<Result<T>>>(url: string,
                                                        config?: AxiosRequestConfig): Promise<R> {
    return this.axiosInstance.get(url, config);
  }

  /**
   * post请求
   * @param url 请求地址
   * @param data 请求参数
   * @param config 请求参数
   * @return 响应
   */
  protected post0<T = any, R = AxiosResponse<Result<T>>>(url: string,
                                                         data?: any,
                                                         config?: AxiosRequestConfig): Promise<R> {
    return this.axiosInstance.post(url, data, config);
  }

  /**
   * put请求
   * @param url 请求地址
   * @param data 请求参数
   * @param config 请求参数
   * @return 响应
   */
  protected put0<T = any, R = AxiosResponse<Result<T>>>(url: string,
                                                        data?: any,
                                                        config?: AxiosRequestConfig): Promise<R> {
    return this.axiosInstance.put(url, data, config);
  }

  /**
   * get请求
   * @param url 请求地址
   * @param config 请求参数
   * @return 响应
   */
  protected delete0(url: string, config?: AxiosRequestConfig): Promise<void> {
    return this.axiosInstance.delete(url, config);
  }
}

export default Http;
